package com.krtech.wecard.config;

import cn.hutool.core.util.StrUtil;
import cn.hutool.db.nosql.redis.RedisDS;
import cn.hutool.setting.Setting;
import cn.hutool.system.SystemUtil;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.ScanResult;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Component
public class WecardRedisTemplate {
	private Jedis jedis;
	private RedisDS redisDS;

	public WecardRedisTemplate(){
		Setting setting = new Setting();
//		setting.set("host", SystemUtil.get("XF_IP","124.223.88.149"));

//		setting.set("host", "101.43.12.157");
		//蚂蚁服务器2
//		setting.set("host", "123.207.207.3");
		setting.set("host", "10.0.16.11");

		setting.set("password", SystemUtil.get("REDIS_PASSWORD","MySql684W3JpuKsI"));

		setting.set("port", SystemUtil.get("REDIS-PORT","6379"));
		setting.set("testOnBorrow", SystemUtil.get("TEST-ON-BORROW",true));
		setting.set("testOnReturn", SystemUtil.get("TEST-ON-RETURN",true));
		setting.set("database",SystemUtil.get("DATABASE","0"));
		redisDS = RedisDS.create(setting, null);
		jedis = redisDS.getJedis();
	}

	public void set(String key,String value){
		Jedis nowJedis = redisDS.getJedis();

		try {
			nowJedis.set(key,value);
		} catch (Exception e) {
			//释放redis对象
			nowJedis.close();;
			e.printStackTrace();
		} finally {
			//返还到连接池
			nowJedis.close();
		}
	}

	/**
	 * 设置成功，返回 1 。设置失败，返回 0
	 * @param key
	 * @param value
	 * @return
	 */
	public Long setNx(String key,String value){
		Jedis nowJedis = redisDS.getJedis();

		try {
			Long setnx = nowJedis.setnx(key, value);
			return setnx;
		} catch (Exception e) {
			//释放redis对象
			nowJedis.close();;
			e.printStackTrace();
		} finally {
			//返还到连接池
			nowJedis.close();
		}
		return null;
	}


	/**
	 * 设置成功，返回 1 。设置失败，返回 0
	 * @param key
	 * @param value
	 * @return
	 */
	public boolean setNx2(String key,String value){
		Jedis nowJedis = redisDS.getJedis();

		try {
			Long setnx = nowJedis.setnx(key, value);
			if (setnx > 0){
				return true;
			}else {
				return false;
			}
		} catch (Exception e) {
			//释放redis对象
			nowJedis.close();;
			e.printStackTrace();
		} finally {
			//返还到连接池
			nowJedis.close();
		}
		return false;
	}

	public Long setList(String paylistId,String machineId){
		Jedis nowJedis = redisDS.getJedis();

		try {
			Long size = nowJedis.lpush(paylistId, machineId);
			return size;
		} catch (Exception e) {
			//释放redis对象
			nowJedis.close();;
			e.printStackTrace();
		} finally {
			//返还到连接池
			nowJedis.close();
		}
		return 0L;
	}

	public Long getListSize(String paylistId){
		Jedis nowJedis = redisDS.getJedis();

		try {
			Long len = nowJedis.llen(paylistId);
			return len;
		} catch (Exception e) {
			//释放redis对象
			nowJedis.close();;
			e.printStackTrace();
		} finally {
			//返还到连接池
			nowJedis.close();
		}
		return 0L;
	}

	public List<String> getList(String paylistId){
		Jedis nowJedis = redisDS.getJedis();

		try {
			Long len = nowJedis.llen(paylistId);
			List<String> list = nowJedis.lrange(paylistId, 0, len);
			return list;
		} catch (Exception e) {
			//释放redis对象
			nowJedis.close();;
			e.printStackTrace();
		} finally {
			//返还到连接池
			nowJedis.close();
		}
		return null;
	}

	public List<String> getSet(String paylistId){
		Jedis nowJedis = redisDS.getJedis();

		try {
			Set<String> smembers = nowJedis.smembers(paylistId);
			List<String> list = new ArrayList<>(smembers);
			return list;
		} catch (Exception e) {
			//释放redis对象
			nowJedis.close();;
			e.printStackTrace();
		} finally {
			//返还到连接池
			nowJedis.close();
		}
		return null;
	}

	/**
	 *
	 * @param paylistId
	 * @param len:要多少个，给10就会返回0-9，共10个
	 * @return
	 */
	public List<String> getListByLen(String paylistId,Long len){
		Jedis nowJedis = redisDS.getJedis();

		try {
			len = len - 1L;

			List<String> list = nowJedis.lrange(paylistId, 0, len);
			return list;
		} catch (Exception e) {
			//释放redis对象
			nowJedis.close();;
			e.printStackTrace();
		} finally {
			//返还到连接池
			nowJedis.close();
		}
		return null;
	}

	/**
	 *
	 * @param key
	 * @param value
	 * @param time:单位，秒
	 */
	public void set(String key,String value,int time){
		Jedis nowJedis = redisDS.getJedis();

		try {
			nowJedis.setex(key,time,value);
		} catch (Exception e) {
			//释放redis对象
			nowJedis.close();;
			e.printStackTrace();
		} finally {
			//返还到连接池
			nowJedis.close();
		}
	}

	public String get(String key){
		Jedis nowJedis = redisDS.getJedis();

		String getResult = null;

		try {
			getResult = nowJedis.get(key);
		} catch (Exception e) {
			//释放redis对象
			nowJedis.close();;
			e.printStackTrace();
		} finally {
			//返还到连接池
			nowJedis.close();
		}
		return getResult;
	}

	public void del(String key){
		Jedis nowJedis = redisDS.getJedis();

		try {
			nowJedis.del(key);
		} catch (Exception e) {
			//释放redis对象
			nowJedis.close();;
			e.printStackTrace();
		} finally {
			//返还到连接池
			nowJedis.close();
		}
	}

	/**
	 * 增
	 */
	public Long incr(String key){
		Long incr = null;
		Jedis nowJedis = redisDS.getJedis();

		try {
			incr = nowJedis.incr(key);
		} catch (Exception e) {
			//释放redis对象
			nowJedis.close();;
			e.printStackTrace();
		} finally {
			//返还到连接池
			nowJedis.close();
		}

		return incr;
	}

	/**
	 * 减
	 */
	public Long decr(String key){
		Long incr = null;
		Jedis nowJedis = redisDS.getJedis();

		try {
			incr = nowJedis.decr(key);
		} catch (Exception e) {
			//释放redis对象
			nowJedis.close();;
			e.printStackTrace();
		} finally {
			//返还到连接池
			nowJedis.close();
		}

		return incr;
	}

	public List<String> scan(String keyword){
		Jedis nowJedis = redisDS.getJedis();

		try {
			// 扫描参数
//			ScanParams scanParams = new ScanParams().match(keyword+"*");
//
//			// 初始游标
//			String cursor = ScanParams.SCAN_POINTER_START;
//
//			// 进行扫描
//			ScanResult<String> 	scanResult = jedis.scan(cursor, scanParams);

			Set<String> keys = nowJedis.keys("*" + keyword + "*");



			return new ArrayList<>(keys);
		} catch (Exception e) {
			//释放redis对象
			nowJedis.close();;
			e.printStackTrace();
		} finally {
			//返还到连接池
			nowJedis.close();
		}
		return null;
	}

	public boolean delKeyword(String keyword){
		Jedis nowJedis = redisDS.getJedis();

		try {

			List<String> scanList = this.scan(keyword);
			for (String key : scanList) {
				nowJedis.del(key);
			}
			return true;
		} catch (Exception e) {
			//释放redis对象
			nowJedis.close();;
			e.printStackTrace();
		} finally {
			//返还到连接池
			nowJedis.close();
		}
		return false;
	}

	/**
	 * 特殊删除，传入的list不删除
	 * @param keyword
	 * @return
	 */
	public boolean delKeyword(String keyword,List<String> undel){
		Jedis nowJedis = redisDS.getJedis();

		try {

			List<String> scanList = this.scan(keyword);
			for (String key : scanList) {
				if (!undel.contains(key)){
					nowJedis.del(key);
				}
			}
			return true;
		} catch (Exception e) {
			//释放redis对象
			nowJedis.close();;
			e.printStackTrace();
		} finally {
			//返还到连接池
			nowJedis.close();
		}
		return false;
	}



	//以下是jedis中的set方法
//	public static void main(String[] args) {
//		WecardRedisTemplate redisTemplate = new WecardRedisTemplate();
////		Long aLong = redisTemplate.luaSetAdd("comment:test:success:" + "1001", "test2");
////		System.out.println(aLong);
//
//		Long decr = redisTemplate.decr("dianzan:6309");
//		System.out.println(decr);
//	}

	public Long luaSetAdd(String paylistId,String machineId){
		Jedis nowJedis = redisDS.getJedis();

		try {

			// Lua脚本：先尝试添加元素，然后返回集合的长度
			String luaScript = "redis.call('SADD', KEYS[1], ARGV[1]); return redis.call('SCARD', KEYS[1]);";

			// 执行Lua脚本
			Object result = jedis.eval(luaScript, Collections.singletonList(paylistId), Collections.singletonList(machineId));

			// 将结果转换为Long（因为SCARD返回的是整数）
			long setSizeAfterAdd = Long.parseLong(result.toString());
			return setSizeAfterAdd;

		} catch (Exception e) {
			//释放redis对象
			nowJedis.close();;
			e.printStackTrace();
		} finally {
			//返还到连接池
			nowJedis.close();
		}
		return 0L;
	}

	public Long setBatchAdd(String key,List<String> machineIdList){
		Jedis nowJedis = redisDS.getJedis();

		try {


			// 执行Lua脚本
			Long count2 = jedis.sadd(key, machineIdList.toArray(new String[0]));

			return count2;

		} catch (Exception e) {
			//释放redis对象
			nowJedis.close();;
			e.printStackTrace();
		} finally {
			//返还到连接池
			nowJedis.close();
		}
		return 0L;
	}

	/**
	 * 判断某元素是否在set中
	 * @param paylistId
	 * @param machineId
	 * @return
	 */
	public boolean judgeSet(String paylistId,String machineId){
		Jedis nowJedis = redisDS.getJedis();

		try {
			//返回值为>0，说明添加成功了，如果返回为0，说明添加失败了
			Boolean judge = nowJedis.sismember(paylistId, machineId);

			return judge;
		} catch (Exception e) {
			//释放redis对象
			nowJedis.close();;
			e.printStackTrace();
		} finally {
			//返还到连接池
			nowJedis.close();
		}
		return false;
	}

	/**
	 * 判断key是否存在
	 *
	 * @param key
	 * @return
	 */
	public boolean exists(String key){
		Jedis nowJedis = redisDS.getJedis();

		try {
			//返回值为>0，说明添加成功了，如果返回为0，说明添加失败了
			Boolean judge = nowJedis.exists(key);

			return judge;
		} catch (Exception e) {
			//释放redis对象
			nowJedis.close();;
			e.printStackTrace();
		} finally {
			//返还到连接池
			nowJedis.close();
		}
		return false;
	}

	/**
	 * 添加元素到set中
	 * @param paylistId
	 * @param machineId
	 * @return
	 */
	public boolean addSet(String paylistId,String machineId){
		Jedis nowJedis = redisDS.getJedis();

		try {
			//返回值为>0，说明添加成功了，如果返回为0，说明添加失败了
			Long sadd = nowJedis.sadd(paylistId, machineId);
			if (sadd > 0){
				return true;
			}
			return false;
		} catch (Exception e) {
			//释放redis对象
			nowJedis.close();;
			e.printStackTrace();
		} finally {
			//返还到连接池
			nowJedis.close();
		}
		return false;
	}

	/**
	 * 获得set的长度
	 *
	 * @param paylistId
	 * @param machineId
	 * @return
	 */
	public boolean setSize(String paylistId,String machineId){
		Jedis nowJedis = redisDS.getJedis();

		try {
			//返回值为>0，说明添加成功了，如果返回为0，说明添加失败了
			Long sadd = nowJedis.sadd(paylistId, machineId);
			if (sadd > 0){
				return true;
			}
			return false;
		} catch (Exception e) {
			//释放redis对象
			nowJedis.close();;
			e.printStackTrace();
		} finally {
			//返还到连接池
			nowJedis.close();
		}
		return false;
	}

	/**
	 * close
	 */
	public void close(){
		jedis.close();
	}

}
